import {
  useCallback,
  FC,
  ReactElement,
  useRef,
  memo,
  useState,
  useEffect,
  MouseEventHandler,
} from "react";
import styled, { css, keyframes } from "styled-components";
import {
  getCommentByBlog,
  IComment,
  ISecondComment,
  sendComment,
} from "../../api/commentApi";
import { userProfileRef } from "../../layout/UserProfile";
import { Button, FlexDiv } from "../BUI";
import LoadIcon from "../BUI/Icon/LoadIcon";
import { HideDownIcon, TalkIcon } from "../BUI/Icon";
import { ThemeBgc, ThemeText } from "../BUI/View/ThemeView";
import { ContentCss } from "../commentStyled";
import CommentItem, { CommentBox, SecondCommentBox } from "./CommentItem";

interface IProps {
  senderId: string;
  blogId: string;
}

interface IReply {
  commentId: string;
  username: string;
  at: string;
  commentIndex: number;
}

const Comment: FC<IProps> = ({ senderId, blogId }): ReactElement => {
  const text = useRef<HTMLTextAreaElement>(null);
  const [loading, setLoading] = useState(false);
  const [comments, setComments] = useState<IComment[]>([]);
  const [reply, setReply] = useState<IReply | null>(null); // 回复评论时

  useEffect(() => {
    getCommentByBlog({ _id: blogId }).then(res => {
      console.log("comment:", res.data);
      if (res && res.data && res.data.code === 0) {
        setComments(res.data.comments);
      }
    });
  }, [blogId]);

  useEffect(() => {
    reply && text.current && text.current.focus();
  }, [reply]);

  const handleSendComment = () => {
    if (!senderId)
      return userProfileRef.current && userProfileRef.current.open();
    if (!text.current || !text.current.value) return;
    setLoading(true);
    const params: Parameters<typeof sendComment>[number] = {
      senderId,
      blogId,
      content: text.current.value,
    };
    if (reply) {
      params.commentId = reply.commentId;
      params.at = reply.at;
      params.replyUser = reply.username;
    }
    sendComment(params).then(({ data }) => {
      console.log("sendComment:", data);
      setLoading(false);
      if (data && data.comment) {
        text!.current!.value = "";
        if (reply) {
          //二级评论发送完毕
          setReply(null);
          const temp = [...comments];
          const target = temp[reply.commentIndex];
          if (target.child) {
            target.child.unshift(data.comment as ISecondComment);
          } else target.child = [data.comment as ISecondComment];
          setComments(temp);
        } else {
          setComments(prev => [data.comment as IComment, ...prev]);
        }
      }
    });
  };

  const handleReply: (reply: IReply) => MouseEventHandler<HTMLSpanElement> =
    useCallback(
      reply => () => {
        setReply(prev =>
          prev ? (prev.commentId === reply.commentId ? null : reply) : reply
        );
      },
      []
    );

  return (
    <Container>
      {comments.map((comment, index) => (
        <CommentBox key={comment._id}>
          <CommentItem
            comment={comment}
            userId={senderId}
            handleReply={handleReply}
            commentIndex={index}
          />
          {comment.child ? (
            <SecondCommentBox>
              {comment.child.map(second => (
                <CommentBox key={second._id}>
                  <CommentItem
                    commentId={comment._id}
                    comment={second}
                    userId={senderId}
                    reply={second.reply[0].username}
                    handleReply={handleReply}
                    commentIndex={index}
                  />
                </CommentBox>
              ))}
            </SecondCommentBox>
          ) : null}
        </CommentBox>
      ))}
      <SendCommentBox reply={!!reply}>
        <div>
          <Title>发表评论 {reply ? ` - 回复 ${reply.username}` : ""}</Title>
          <textarea ref={text} />
          <FlexDiv justify="space-between">
            <Button
              data-key="send-btn"
              justify="center"
              onClick={handleSendComment}
            >
              {loading ? <LoadIcon /> : null}
              发送
            </Button>
            <TalkIcons />
          </FlexDiv>
        </div>
        <section>
          <Button justify="center" onClick={() => setReply(null)}>
            <HideDownIcon />
            收起
          </Button>
        </section>
      </SendCommentBox>
    </Container>
  );
};

export default memo(Comment);

const Title = styled.span`
  font-weight: bold;
`;

const slideUp = keyframes`
  0%{transform: translateY(100%);};
  100%{transform: translateY(0);};
`;

const blink = keyframes`
90%{top: 0.3rem};
100%{top: 0.7rem};
`;

const TalkIcons = () => (
  <TalkIconGroup>
    <TalkIcon />
    <TalkIcon />
  </TalkIconGroup>
);

const TalkIconGroup = styled.div.attrs({ "data-talk-icon": "" })`
  width: 4rem;
  display: flex;
  position: relative;

  ::before {
    content: "";
    position: absolute;
    background: ${props => props.theme.text};
    width: 0.7rem;
    height: 0.5rem;
    left: 1rem;
    top: 0.3rem;
    animation: ${blink} 3s linear infinite reverse;
  }

  ::after {
    content: "";
    position: absolute;
    background: ${props => props.theme.button.bg};
    width: 0.7rem;
    height: 0.5rem;
    right: 1rem;
    top: 0.3rem;
    animation: ${blink} 4s linear infinite reverse;
  }

  & > svg {
    width: 2rem;
    height: 2rem;
    fill: ${props => props.theme.text};
  }
  & > svg:last-child {
    transform: rotateY(180deg);
    fill: ${props => props.theme.button.bg};
  }
`;

const commentInput = css`
  z-index: ${props => props.theme.index.emergeMobile};
  position: fixed;
  bottom: 0;
  left: 0;
  padding: 1rem 2rem;
  animation: ${slideUp} 0.3s linear;
  box-shadow: inherit;

  & > section {
    display: flex;

    @media screen and (max-width: ${props => props.theme.media.phone}) {
      position: absolute;
      right: 3.5rem;
      top: 1.5rem;
      button {
        width: 5rem;
      }
      & ~ div[data-talk-icon] {
        transform: translateX(0);
      }
    }
  }
  div[data-talk-icon] {
    transition: transform 0.3s linear 0.3s;
    @media screen and (min-width: ${props => props.theme.media.phone}) {
      transform: translateX(6rem);
    }
  }
`;

const SendCommentBox = styled.div<{ reply: boolean }>`
  width: 100%;
  display: flex;
  margin-top: 1rem;
  ${ThemeBgc};

  & > section {
    display: none;
    align-items: center;
    margin-left: 1rem;
    flex-direction: column;
    justify-content: space-between;
    width: 4rem;
    & > button {
      width: 100%;
    }
  }

  ${props => props.reply && commentInput};

  & > div {
    display: flex;
    flex-direction: column;
    box-shadow: 0 0 10px 0 #ccc;
    border-radius: 10px;
    padding: 1rem;
    flex: 1;

    button {
      height: 2rem;
      letter-spacing: 2px;
      width: 10rem;
    }
  }

  textarea {
    border: 1px solid ${props => props.theme.fg};
    padding: 1rem;
    border-radius: inherit;
    height: 11rem;
    margin: 1rem 0;
    resize: none;
    outline: none;
    background-color: transparent;
    transition: all 0.3s linear;
    font-size: 1rem;
    &:focus {
      background-color: ${props => props.theme.button.bg};
      color: #fff;
    }
  }
`;

const Container = styled.div`
  ${ContentCss};
  ${ThemeBgc};
  ${ThemeText};
  width: 100%;
  overflow: hidden;
  margin: 0;
  margin-top: 1rem;
`;
